/*
 *   This File is Part of CuteOgre Game Engine
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *	Copyright 2010 Alexandre Pires ( c.alexandre.pires@gmail.com )
 *  Created on: 2010/08/22
 */


#ifndef VORBISSTREAM_H_
#define VORBISSTREAM_H_

#include "IOggStream.h"

#include "vorbis/codec.h"

#include <QSharedPointer>
#include <QMutex>

class OggFile;

class VorbisStream: public IOggStream {

	friend class OggFile;

public:
	virtual ~VorbisStream();

	inline int getVersion() const {

		return mInfo.version;
	}

	inline int getChannels() const {

		return mInfo.channels;
	}

	inline long getRate() const {

		return mInfo.rate;
	}

	inline long getBitrateUpper() const {

		return mInfo.bitrate_upper;
	}

	inline long getBitrateNominal() const {
		return mInfo.bitrate_nominal;
	}

	inline long getBitrateLower() const {
		return mInfo.bitrate_lower;
	}

	inline long getBitrateWindow() const {
		return mInfo.bitrate_window;
	}

	QString streamInfo() const {
		return QString(
				"VorbisStream (%7) -> Version: %1, channels: %2, rate: %3, bitrate nominal: %4, bitrate upper: %5, bitrate lower: %6").arg(
				getVersion()).arg(getChannels()).arg(getRate()).arg(
				getBitrateNominal()).arg(getBitrateUpper()).arg(getBitrateLower()).arg(
				mSerial);
	}

	inline int getSerial() const {
		return mSerial;
	}

	inline StreamType getStreamType() const {
		return IOggStream::TYPE_VORBIS;
	}

	inline bool isActive() {
		return mActive;
	}

	inline void disable () {
		mActive = false;
	}

	long read(char *buffer, int length, int bigendianp, int word, int sgned);

protected:

	VorbisStream(int rSerial = -1, OggFile* rFile = 0);

	void processHeaders();

	inline void lockState() {
		mMutex.lock();
	}

	inline void unlockState() {
		mMutex.unlock();
	}

	inline ogg_stream_state* getState() {
		return &mState;
	}

	static bool checkHeaderSignature(ogg_packet* rPacket);
	static bool checkHeaderSignature(ogg_page* rPage);

private:
	bool handle_vorbis_header(ogg_packet* rPacket);
	static int hostIsBigEndian();

protected:
	/* OGG stream state*/
	int mSerial;
	ogg_stream_state mState;

	/* Vorbis info*/
	vorbis_info mInfo;
	vorbis_comment mComment;
	vorbis_dsp_state mDsp;
	vorbis_block mBlock;

	OggFile* mFile;
	QMutex mMutex;
	bool mHeaderDone, mActive;
};

typedef QSharedPointer<VorbisStream> VorbisStreamPtr;


#endif /* VORBISSTREAM_H_ */
